package com.hjw.controller;

import cn.dev33.satoken.util.SaResult;
import com.hjw.dao.CommentDao;
import com.hjw.entity.*;
import com.hjw.service.*;
import com.hjw.utils.Utils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.util.*;

/**
 * <p>Project:Academic - PublicController<p>
 *
 * @author IvanWei玮 -- maste
 * @version 1.0
 * @DataTime 2025/4/12 15:02
 * @since 1.8
 */
@Slf4j
@RestController
@RequestMapping("/api/public")
public class PublicController {

    @Autowired
    private LargeFileService largeFileService;
    @Autowired
    private TypeService typeService;
    @Autowired
    private HotService hotService;
    @Autowired
    private BookService bookService;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private UserService userService;
    @Autowired
    private CommentService commentService;

    @GetMapping("/showImg/{id}")  // /api/public/showImg/
    public void getImg(@PathVariable("id")String id, HttpServletResponse response) throws IOException {
        LargeFile largeFile = largeFileService.findOne(id);
        if (largeFile == null) {
            log.error("图片不存在");
            return;
        }
        byte[] one = (byte[]) largeFile.getContent();
        OutputStream os = response.getOutputStream();
        response.setContentType("image/jpeg");
        os.write(one);
        os.flush();
    }

    @GetMapping("/getType") // /api/public/getType
    public SaResult getType() {
        List<Type> all = typeService.findAll();
        //一级类型
        List<Type> category = new ArrayList<>(10);
        // 二级类型
        List<Type> types = new ArrayList<>(10);
        // 一级类型id
        Set<Integer> id = new HashSet<>(10);

        for (Type type : all) {
            if (type.getPid() == 0) {
                category.add(type);
                id.add(type.getId());
                continue;
            }
            types.add(type);
        }

        //得到所有二级类型的返回数组
        List<Object> list = new ArrayList<>();

        for (Integer i : id) {
            List<Object> t = new ArrayList<>();
            t.add(i);
            for (Type type : types) {
                if (type.getPid() == i) {
                    t.add(type);
                }
            }
            if (t.size() == 1) {
                continue;
            }
            list.add(t);
        }
        Map<String, Object > map = new HashMap<>(2);
        map.put("category", category);
        map.put("types", list);
        return SaResult.get(200, "获取成功", map);
    }

    @GetMapping("/findHot/{type}/{num}") // /api/public/findHot/{type}/{num}
    public SaResult findHot(@PathVariable("type") int type, @PathVariable("num") int num){

        Map<String, Object> map = new HashMap<>(2);
        if (type > 0) {
            map.put("type", type);
        }
        if (num > 0) {
            map.put("num", num);
        }

        List<Hot> hots = hotService.findByParams(map);
        return SaResult.get(200,"获取成功", hots);
    }

    @GetMapping("/book/findTopSale/{num}") // /api/public/book/findTopSale/{num}
    public SaResult findTop(@PathVariable("num") Integer num){
        if (num == null) {
            num = 5;
        }
        if (num < 1) {
            num = 1;
        }
        if (num > 20) {
            num = 20;
        }
        return SaResult.get(200, "获取成功", bookService.findTop(num));
    }

    @PostMapping("/user/registration") // /api/public/user/registration
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public SaResult register(@RequestParam Map<String, Object> map, @RequestParam(value = "mypic", required = false) MultipartFile myfile) throws IOException {
        log.info("注册信息：" + map);
        if (myfile == null || myfile.isEmpty()){
            return SaResult.get(-200, "头像为空，注册失败", null);
        }
        if(map == null || map.isEmpty()){
            return SaResult.get(-200, "注册信息为空，注册失败", null);
        }

        String newPicId = UUID.randomUUID().toString().replace("-", "");
        LargeFile largeFile = new LargeFile(newPicId, myfile.getOriginalFilename(), myfile.getBytes());

        int add = largeFileService.add(largeFile);
        if (add == 0){
            return SaResult.get(-200, "系统异常，头像上传失败", null);
        }
        log.info("头像上传成功:{}", largeFile);
        User user = new User();
        user.setAccount(map.get("account").toString());
        user.setPassword(passwordEncoder.encode(map.get("password").toString()));
        // 韭菜角色
        user.setRole("usr");
        user.setPhone(map.get("phone").toString());
        user.setNickname(map.get("nickname").toString());
        user.setVip(Integer.parseInt(map.get("vip").toString()));
        user.setAddr(map.get("addr").toString());
        user.setImg(newPicId);
        // 韭菜属性
        user.setClosed(0);
        log.info("注册信息：{}", user);
        int registered = userService.add(user);

        if (registered == 0){
            return SaResult.get(-200, "注册失败", null);
        }
        return SaResult.get(200, "注册成功", user);
    }

    @GetMapping("/book/findPage/{state}/{num}/{typeId}") // /api/public/book/findPage/{state}/{num}/{typeId}
    public SaResult findPage(@PathVariable("state") Integer state,
                           @PathVariable("num") Integer num,
                           @PathVariable("typeId") Integer typeId){
        Map<String, Object> map = new HashMap<>(3);
        if (num == null || num < 1){
            num = 1;
        }
        map.put("num", num);
        if (typeId > 0) {
            map.put("typeid", typeId);
        }
        // 获取总记录数
        int count = bookService.count(map);
        // 计算总页数
        int totalPages = (int) Math.ceil((double) count / num);
        if (state > totalPages){
            state = totalPages;
        }
        int stateRow = 0;
        if (state > 0){
            stateRow = (state - 1) * num;
        }
        map.put("state", stateRow);
        if (typeId != 0){
            Type t = typeService.findById(typeId);
            log.info("pid:{}", t);
            if (t.getPid() == 0){
                map.remove("typeid");
                map.put("pid",typeId);
            }
        }

        log.info("查询条件：{}", map);
        List<Book> books = bookService.findByPage(map);
        Map<String, Object> result = new HashMap<>(2);
        result.put("books", books);
        result.put("count", count);
        return SaResult.get(200, "获取成功", result);
    }

    @PostMapping("/book/findPageKey/") // /api/public/book/findPageKey/
    public SaResult findPageKey(@RequestBody Map<String, Object> map){
        log.info("查询条件：{}", map);
        if (map == null || !map.containsKey("curPage") || !map.containsKey("lines") || !map.containsKey("key")){
            return SaResult.get(-200, "参数错误", null);
        }
        int num = Integer.parseInt(map.get("lines").toString());
        int state = Integer.parseInt(map.get("curPage").toString());
        if (num < 1){
            num = 1;
        }
        map.put("num", num);
        int count = bookService.count(map);
        // 计算总页数
        int totalPages = (int) Math.ceil((double) count / num);
        if (state > totalPages){
            state = totalPages;
        }
        int stateRow = 0;
        if (state > 0){
            stateRow = (state - 1) * num;
        }
        map.put("state", stateRow);
        List<Book> books = bookService.findByPageKey(map);
        // 此处对查询出来的书籍的对应key做高亮返回前端
        for (Book b :books) {
            b.setName(Utils.highlightText(b.getName(), map.get("key").toString()));
            b.setMaker(Utils.highlightText(b.getMaker(), map.get("key").toString()));
            b.setAuthor(Utils.highlightText(b.getAuthor(), map.get("key").toString()));
            b.setInfo(Utils.highlightText(b.getInfo(), map.get("key").toString()));
            log.info("高亮后的结果：{}", b);
        }

        Map<String, Object> result = new HashMap<>(2);
        result.put("books", books);
        result.put("count", count);
        return SaResult.get(200, "获取成功", result);
    }

    @GetMapping("/book/findById/{id}") // /api/public/book/findById/{id}
    public SaResult findByBookId(@PathVariable("id") Integer bid){
        Book book = bookService.findById(bid);
        return SaResult.get(200,"获取成功", book);
    }

    @GetMapping("/comment/{bookid}")
    public SaResult getComment(@PathVariable("bookid") String bookid){
        Map<String,Object> map = new HashMap<>();
        map.put("bookid", bookid);
        List<Comment> comments = commentService.getComment(map);
        if (comments == null){
            return SaResult.get(-200, "获取失败", null);
        }
        return SaResult.get(200, "获取成功", comments);
    }

}
